Onomastikon Module and Database
The Onomastikon Module is designed specifically to handle the random creation of names for Character and Starship objects (the word "onomastikon" itself is an earlier form of the word "onomasticon", which is defined as "A book, list, or vocabulary of names, especially of people". The basic architecture of the module is similar to other modules within the game that handle strings and dictionaries. This module is required by the Communication Mechanics, Interface and Engine, Personnel/Crew Assignment Module and Trading and Commerce Module specifically, though there may be some other applications available in other modules. While a small portion of the game, the onomastikon module is nonetheless important as it adds a greater sense of randomization to encounters (i.e. it will help make it seem like the player is meeting up with different aliens during the course of their adventures). All code for the onomastikon object as well as the required child classes is located in the onomastikon.py file. Data Structure of the Onomastikon Object The following list is an indication of the various variables and methods that will be included in an onomastikon object. This list contains the final methods and variables included in the module. Onomastikon objects are meant to be used as direct objects, with no parent objects. Onomastikon have two children objects which are used to properly parse the XML files containing the data pertinent to the object. Only one onomastikon object is meant to be used in the game, and it is meant to be loaded by the core engine as the game is initially loading. Their data structure is as follows: *Class: onomastikon **Hash/Library: vNameLibrary **Method: __init__ () **Method: szGetCharacterName (name) **Method: szGetShipName (name) **Method: __szGetName (szFile, nTarget) Methods __init__ () Method The onomastikon's initializer method begins by declaring the vNameLibrary dictionary. It then creates an XML parser for the class and tells the parser to ignore XML namespaces (this is used to ease the accessibility of the XML data). Once that's done, the method creates a masterList SAX content handler object; the initializer for this SAX handler object creates a List called vFiles, and has a method called startElement which looks for XML items with the element name "file" and appends the "name" attribute into vFiles (this is done to load a master list of filenames, each of which contains the name data for the races in the game). With the masterList object created, the initializer tells the parser to use the masterList object as a content handler and to parse the file; this does the actual loading of the filenames into the masterList object. The initializer then enters into a for loop, iterating once for each entry in the masterList object's vFile List. In the loop, it creates an xmlHandler SAX content handler object; the initializer for this SAX handler object creates four Lists (vGivenMale, vGivenFemale, vSur, and vShip), a four strings called szName, szSpecialShipText, szSpecialNameText, and szPatronym, and two integer variables called nSyl and nShipswitch. Like the masterList object, the xmlHandler object has a method called startElement. This method looks for XML items with the element name "species" and pulls several variables out of the "species" attributes (szName is set equal to "name", nSyl is set equal to "syl" and re-cast as an integer, nShipswitch is set equal to "shipswitch", and szPatronym is set equal to "patronym). szSpecialNametext is set equal to "specnametext" and szSpecialShipText is set equal to "specshiptext", but only if those attributes are present in the species element. With these basic variables set, the function then proceeds to search for various elements. For items with the element "sur" or "ship", the "val" attribute is appended to vSur or vShip, respectively. If, however, the "given" element is encountered, a check is required to see which list to appended it to. This check involves a search for the attribute "gender"; if the attribute does not exist, or if it is anything other than "female", the "val" attribute is appended to vGivenMale. If, however, the "gender" attribute is present and equals "female", the "val" attribute is appended to vGivenFemale. Once the initializer has created the xmlHandler object, it tells the parser to use the xmlHandler object as a content handler. It then checks to see if the next file indicated in the masterList object's vFile List exists; if it doesn't, the loop progresses to its next iteration. If the file does exist, the parser will parse the xmlHandler object; this does the actual loading of the data into the xmlHandler object. With that data loaded, the initializer creates a dictionary entry for vNameLibrary, using the xmlHandler object's szName string as the key and the xmlHandler object itself as the value associated with that key. The xmlHandler object goes out of phase when the loop iterates, assuring that a new object (and therefore new data) are created with each iteration. Once the loop completes its final iteration, the initializer routine is complete. szGetCharacterName (name) and szGetShipName (name) Methods The onomastikon's functionality comes from one of these two public methods, both of which return a finished name (a string) to the caller. Both functions require a "name" argument; this variable is a string and must match one of the keys in the onomastikon object's vNameLibrary dictionary. These functions are essentially identical; they pass along the species name given to them to the private method __szGetName (name, nTarget) along with a value for that function's nTarget argument (which determines the kind of name that function will be asked to produce), and set the result (which should be a string) equal to a value called szFinal. szFinal is then returned to the caller. __szGetName (szFile, nTarget) Method The heart of the onomastikon code is the private method __szGetName (szFile, nTarget), which assembles a name based upon the arguments (the first a string containing the name of the desired race for which the name is being built, the second being an integer which determines if a character name or ship name will be produced) passed to it by either the szGetCharacterName (name) or szGetShipName (name) method and returns the finished name to the calling method. When called, the method declares a holder string (szFinal) and enters into a try block; the exception for this block returns a default string "‹flubbed›" should something go wrong, so the method will always be able to return a string even if an error state occurs. The method then retrieves the xmlHandler object stored in the onomastikon object's vNameLibrary dictionary whose key matches the race name (szFile) passed to the function (locally, this object is called as localRace). The method then checks a number of conditions, based upon the value of nTarget (what type of name is needed) and the values of localRace's nShipSwitch and nSyl variables. If a ship name is requested and a ship list is available (denoted by a value of 1 for localRace.nShipswitch), the method will check to see if there is any available text in the localRace object's szSpecialShipText variable. If there is, that text is appended to szFinal. Regardless of whether special text is added or not, the method will then select at random a number from one to x, where x is the number of entries in the localRace object's vShip list. The method takes the string in the indicated position of vShip and appends it to szFinal. If a ship name is requested but there is no ship name list available (denoted by a value of 0 for localRace.nShipswitch), the method will first check for special ship text as above and append it to szFinal if found. The final ship name will be generated out of the surnames list, localRace.vSur. To generate the ship's name, the method will pick three numbers at random from one to x, where x is the number of entries in the localRace object's vSur list. The method takes the strings from the indicated positions in vSur and appends them to szFinal. If a character name is requested, the method will begin by checking for any available text in the localRace object's szSpecialNameText variable. If there is, that text is appended to szFinal. Next, the method will determine if a male or female name will be generated. To do this, the method will check to see if there are any entries in localRace's vGivenFemale list. If there are, the method will select one of the two lists (vGivenMale or vGivenFemale) from which to draw names. The method defaults to using the vGivenMale list in the event that there are no names available in the vGivenFemale list. If neither list has any names, the method will not attempt to draw any names from either list, going straight to surnames. Regardless of which list is used, the method will then select at random a number from one to x, (where x is the number of entries in the localRace indicated list) and append the string in the indicated position of that list to szFinal. Once a given name is selected, the method goes into a for loop, which will iterate a number of times based upon the value of localRace's nSyl variable. The loop first checks to make sure there are names in localRace's vSur list (used mainly as a means of preventing errors). Once it's confirmed there are names present in vSur, the method will select at random a number from one to x (where x is the number of entries in the vSur list) and append the string in the indicated position to szFinal. Once the loop has run through its final iteration, the method will then check the value of localRace's szPatronym variable. If it equals true, it will append the word "daughter" or "son" to the end of szFinal; which word is appended solely depends upon the gender of the name generated (this will default to "son" in the event that patronyms are indicated but seperate gender name lists are not provided). Regardless of what type of name is created, the routine will do a couple of things before returning the final result. First, it will check to see if anything was actually created. If nothing was created, the method will return the string "‹default›" to the caller; this will indicate that there were no errors within the method, but no name was actually generated (this should only be possible if the XML file has empty name lists). If something was created, the method will change the final string to title case format (capitalizing all words in the string), and return this final formatted string to the caller. XML The onomastikon object is largely XML driven; this will keep it flexible up until SF3's design is finalized (i.e. species can be added and removed from the game freely, based upon what data is available in the XML files). There are two different XML handlers used by onomastikon objects, each designed to handle different elements. It should therefore be obvious that the onomastikon object requires two different types of XML files, one type for the masterList handler (this consists of a single file, master_list.xml) and another for the xmlHandler class (this consists of one file per species in the game, and is of the file form (Species Name)_names.xml). The following briefly goes over what data is located in these two XML file types. master_list.xml File The file "master_list.xml" is designed as a master filename list. Under the root element, each entry in the XML file has an empty "file" element, which also contains a "name" attribute. The name attribute always contains the name of a file which the onomastikon object will search for while it's being initialized. A desired filename must be added to this list if a list of names needs to be added into the game. Sample structure of the master_list.xml file: ‹?xml version="1.0" ?› ‹root› ‹file name="aeoruiiaeo_names.xml" /› ... ‹file name="xxr_names.xml" /› ‹/root› (Species Name)_names.xml Files There are a number of other XML files that correspond to filenames located in the master_list.xml file. Each one of these files contains the name data for an entire species in game. Under the root element, entrys are listed as being part of one of four categorical elements: "species", "givennames", "surnames", and "shipnames". If there are no entries under a category, the element is still included in the file but is left empty. The species element is always left empty. It always contains these attributes: "name", "syl", "shipswitch", and "patronym". Some species elements may contain "specshiptext" and "specnametext" attributes; these are always optional. Finally, some lists may contain an "id" attribute; this is a holdover from an older version of the SF3 code and can be ignored. Entries under the "givennames", "surnames" and "shipname" categorical elements have a similar structure, though the entry elements differ ("given" for givennames, "sur" for surnames, and "ship" for shipnames). All entries have a "val" attribute which contains the actual string the game will use to make names. Additionally, some "given" entries may have a "gender" attribute; this tells the generator the list in which the givenname will be located (vGivenMaleNames or vGivenFemaleNames). Finally, these entries may also have an "id" element; again, these can be ignored. Even if a file is indicated in the master_list, there must be an actual file in existence for the game to load up names from that file. Any lists indicated on the master_list that aren't actually present in the same directory are simply ignored. Sample structure of a (Species Name)_names.xml file (in this case, human_names.xml): ‹?xml version="1.0" ?› ‹root› ‹species name="Human" id="1" syl="1" shipswitch="1" patronym="False" specshiptext="I.S.S. " /› ‹givennames› ‹given id="1" val="Aakesh" gender="male" /› ... ‹given id="200" val="Zoe" gender="female" /› ‹/givennames› ‹surnames› ‹sur id="1" val=" Aaltonen"/› ... ‹sur id="16345" val=" Zylberstein"/› ‹/surnames› ‹shipnames› ‹ship id="1" val="Abiko"/› ... ‹ship id="750" val="Zorba"/› ‹/shipnames› ‹/root› Module Status This is current as of January 31, 2011. The code for this module is 100% complete and ready to be integrated into the game's Core Module. At this point, an XML file exists for all species planned in the game, and two additional "spare" sets are also available, should additional aliens be added or should an existing name list be deemed unsuitable for the game (unlikely, but possible). Ship names for certain alien species are still being considered, but at this point it looks like it will be unnecessary to prepare specific ship names for any species besides Humans (and, by extension, the Umanu). ---- NEXT: Main Menu Module PREVIOUS: Event and Plot Handler Module TOP ----